package com.loong.android.tools;

import static android.content.Context.CONNECTIVITY_SERVICE;

import java.lang.Thread;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.provider.Settings;
import android.telephony.TelephonyManager;

import com.loong.android.utils.ContextUtils;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

/**
 * 网络操作工具类
 */
public class Network {
    /**
     * 获取指定网页的源码
     * @param targetUrl 目标网址
     * @param encoding 编码一般为 utf-8 或 gbk， 默认为 utf-8
     * @param timeout 限定时间，超时则返回，默认5000, 即5秒。
     */
    public static String getWebPageHtml(final String targetUrl, final String encoding, final int timeout) {
        if (targetUrl == null || targetUrl.length() <= 0 || encoding == null || encoding.length() <= 0 || timeout < 1) return "";
        final String[] responseHtml = {""};
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    URL url = new URL(targetUrl);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setConnectTimeout(timeout);
                    conn.setRequestMethod("GET");
                    if (conn.getResponseCode() == 200) {
                        InputStream inputStream = conn.getInputStream();
                        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                        byte[] buffer = new byte[1024];
                        int len = 0;
                        while ((len = inputStream.read(buffer)) != -1) {
                            outStream.write(buffer, 0, len);
                        }
                        responseHtml[0] = new String(outStream.toByteArray(), encoding);
                        inputStream.close();
                        outStream.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
        try {
            thread.join(timeout);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return responseHtml[0];
    }

    /**
     * 获取指定网页的源码
     * @param targetUrl 目标网址
     * @param encoding 编码一般为 utf-8 或 gbk， 默认为 utf-8
     */
    public static String getWebPageHtml(String targetUrl, String encoding) {
        return getWebPageHtml(targetUrl, encoding, 5000);
    }

    /**
     * 获取指定网页的源码
     * @param targetUrl 目标网址
     * @param timeout 限定时间，超时则返回，默认5000, 即5秒。
     */
    public static String getWebPageHtml(String targetUrl, int timeout) {
        return getWebPageHtml(targetUrl, "UTF-8", timeout);
    }

    /**
     * 获取指定网页的源码
     * @param targetUrl 目标网址
     */
    public static String getWebPageHtml(String targetUrl) {
        return getWebPageHtml(targetUrl, "UTF-8");
    }

    /**
     * 获取网络文件
     * @param fileUrl 网络文件地址
     * @param timeout 限定时间，超时则返回，默认60000, 即60秒。
     */
    public static byte[] getWebFile(final String fileUrl, final int timeout) {
        if (fileUrl == null || fileUrl.length() <= 0 || timeout < 1) return new byte[0];
        final byte[][] responseBytes = {new byte[0]};
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    URL url = new URL(fileUrl);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setConnectTimeout(timeout);
                    conn.setRequestMethod("GET");
                    if (conn.getResponseCode() == 200) {
                        InputStream inputStream = conn.getInputStream();
                        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                        byte[] buffer = new byte[1024];
                        int len = 0;
                        while ((len = inputStream.read(buffer)) != -1) {
                            outStream.write(buffer, 0, len);
                        }
                        responseBytes[0] = outStream.toByteArray();
                        inputStream.close();
                        outStream.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
        try {
            thread.join(timeout);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return responseBytes[0];
    }

    /**
     * 获取网络文件
     * @param fileUrl 网络文件地址
     */
    public static byte[] getWebFile(final String fileUrl) {
        return getWebFile(fileUrl, 60000);
    }

    /**
     * 打开网络设置界面，注意只能在窗口的上下文下调用本函数。
     */
    public static void openNetworkSetting() {
        Activity activity = ContextUtils.getActivity();
        if (activity == null) return;
        activity.startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
    }

    /**
     * 调用系统默认的浏览器打开网址，注意只能在窗口的上下文下调用本函数。
     * @param url 网址
     */
    public static void openUrl(String url) {
        Activity activity = ContextUtils.getActivity();
        if (activity == null) return;
        Intent intent = new Intent();
        intent.setAction("android.intent.action.VIEW");
        Uri content_url = Uri.parse(url);
        intent.setData(content_url);
        activity.startActivity(intent);
    }

    /**
     * 获取网络类型，注意需要读取网络状态(ACCESS_NETWORK_STATE)权限
     * @param context 上下文
     * @return 0=2G; 1=3G; 2=4G; 3=WIFI; 4=其他; 获取失败返回-1
     */
    public static int GetNetworkType(Context context) {
        if (context == null) return -1;
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
        if (cm == null) return -1;
        @SuppressLint("MissingPermission")
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
        if (networkInfo == null || !networkInfo.isConnected()) return -1;
        int type = networkInfo.getType();
        if (type == ConnectivityManager.TYPE_WIFI) return 3;
        if (type == ConnectivityManager.TYPE_MOBILE) {
            String _strSubTypeName = networkInfo.getSubtypeName();
            int networkType = networkInfo.getSubtype();
            switch (networkType) {
                case TelephonyManager.NETWORK_TYPE_GPRS:
                case TelephonyManager.NETWORK_TYPE_EDGE:
                case TelephonyManager.NETWORK_TYPE_CDMA:
                case TelephonyManager.NETWORK_TYPE_1xRTT:
                case TelephonyManager.NETWORK_TYPE_IDEN: //api<8 : replace by 11
                    return 0;//2G
                case TelephonyManager.NETWORK_TYPE_UMTS:
                case TelephonyManager.NETWORK_TYPE_EVDO_0:
                case TelephonyManager.NETWORK_TYPE_EVDO_A:
                case TelephonyManager.NETWORK_TYPE_HSDPA:
                case TelephonyManager.NETWORK_TYPE_HSUPA:
                case TelephonyManager.NETWORK_TYPE_HSPA:
                case TelephonyManager.NETWORK_TYPE_EVDO_B: //api<9 : replace by 14
                case TelephonyManager.NETWORK_TYPE_EHRPD:  //api<11 : replace by 12
                case TelephonyManager.NETWORK_TYPE_HSPAP:  //api<13 : replace by 15
                    return 1;//3G
                case TelephonyManager.NETWORK_TYPE_LTE:    //api<11 : replace by 13
                    return 2;//4G
                default:
                    // http://baike.baidu.com/item/TD-SCDMA 中国移动 联通 电信 三种3G制式
                    if (_strSubTypeName.equalsIgnoreCase("TD-SCDMA") ||
                            _strSubTypeName.equalsIgnoreCase("WCDMA") ||
                            _strSubTypeName.equalsIgnoreCase("CDMA2000")) {
                        return 1;//3G
                    }
            }
        }
        return 4;
    }


    /**
     * 获取内网IP地址(IPV4)
     */
    public static String getLocalAddress() {
        try {
            Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
            while (en.hasMoreElements()) {
                NetworkInterface networkInterface = en.nextElement();
                Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
                while (inetAddresses.hasMoreElements()) {
                    InetAddress inetAddress = inetAddresses.nextElement();
                    if(!inetAddress.isLoopbackAddress() && (inetAddress instanceof Inet4Address)){
                        return inetAddress.getHostAddress();
                    }
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取所有的内网IP地址
     */
    public static String[] getAllLocalAddress() {
        try {
            List<String> output = new ArrayList<>();
            Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
            while (en.hasMoreElements()) {
                NetworkInterface networkInterface = en.nextElement();
                Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
                while (inetAddresses.hasMoreElements()) {
                    InetAddress inetAddress = inetAddresses.nextElement();
                    output.add(inetAddress.getHostAddress());
                }
            }
            return output.toArray(new String[0]);
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return null;
    }
}
